{
 "cells": [
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**问题：**\n",
    "假设你正在为一个电影推荐系统设计一个简单的KNN算法。我们有以下一些用户的电影评分数据，数据由两个特征组成：用户对电影A和电影B的评分，分别在1-5之间。用户的标签（电影类型偏好）是动作片（标签0）或者是喜剧片（标签1）。我们有一个新用户，他给电影A评分为3，电影B评分为4。请问这个用户可能偏好哪种类型的电影？\n",
    "\n",
    "**数据：**\n",
    "\n",
    "| 用户   | 电影A评分 | 电影B评分 | 偏好类型 |\n",
    "| ------ | --------- | --------- | -------- |\n",
    "| 用户1  | 5         | 1         | 动作片   |\n",
    "| 用户2  | 4         | 2         | 动作片   |\n",
    "| 用户3  | 2         | 5         | 喜剧片   |\n",
    "| 用户4  | 1         | 4         | 喜剧片   |\n",
    "| 用户5  | 3         | 2         | 动作片   |\n",
    "| 用户6  | 2         | 5         | 喜剧片   |\n",
    "\n",
    "你需要做以下步骤：\n",
    "1. 构造数据\n",
    "2. 创建KNN模型\n",
    "3. 使用数据训练模型\n",
    "4. 预测新用户的喜好"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 0. 引入核心包"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "from sklearn.neighbors import KNeighborsClassifier"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 1. X, y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "X = np.array([[5, 1], [4, 2], [2, 5], [1, 4], [3, 2], [2, 5]])  # 用户的电影评分数据\n",
    "\n",
    "y = np.array([0, 0, 1, 1, 0, 1])  # 0表示动作片，1表示喜剧片"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 2. 创建 KNN 模型\n",
    "k = 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "k = 1 \n",
    "knn = KNeighborsClassifier(n_neighbors=k)  # 创建 KNN 模型"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 3. 训练模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<style>#sk-container-id-1 {color: black;}#sk-container-id-1 pre{padding: 0;}#sk-container-id-1 div.sk-toggleable {background-color: white;}#sk-container-id-1 label.sk-toggleable__label {cursor: pointer;display: block;width: 100%;margin-bottom: 0;padding: 0.3em;box-sizing: border-box;text-align: center;}#sk-container-id-1 label.sk-toggleable__label-arrow:before {content: \"▸\";float: left;margin-right: 0.25em;color: #696969;}#sk-container-id-1 label.sk-toggleable__label-arrow:hover:before {color: black;}#sk-container-id-1 div.sk-estimator:hover label.sk-toggleable__label-arrow:before {color: black;}#sk-container-id-1 div.sk-toggleable__content {max-height: 0;max-width: 0;overflow: hidden;text-align: left;background-color: #f0f8ff;}#sk-container-id-1 div.sk-toggleable__content pre {margin: 0.2em;color: black;border-radius: 0.25em;background-color: #f0f8ff;}#sk-container-id-1 input.sk-toggleable__control:checked~div.sk-toggleable__content {max-height: 200px;max-width: 100%;overflow: auto;}#sk-container-id-1 input.sk-toggleable__control:checked~label.sk-toggleable__label-arrow:before {content: \"▾\";}#sk-container-id-1 div.sk-estimator input.sk-toggleable__control:checked~label.sk-toggleable__label {background-color: #d4ebff;}#sk-container-id-1 div.sk-label input.sk-toggleable__control:checked~label.sk-toggleable__label {background-color: #d4ebff;}#sk-container-id-1 input.sk-hidden--visually {border: 0;clip: rect(1px 1px 1px 1px);clip: rect(1px, 1px, 1px, 1px);height: 1px;margin: -1px;overflow: hidden;padding: 0;position: absolute;width: 1px;}#sk-container-id-1 div.sk-estimator {font-family: monospace;background-color: #f0f8ff;border: 1px dotted black;border-radius: 0.25em;box-sizing: border-box;margin-bottom: 0.5em;}#sk-container-id-1 div.sk-estimator:hover {background-color: #d4ebff;}#sk-container-id-1 div.sk-parallel-item::after {content: \"\";width: 100%;border-bottom: 1px solid gray;flex-grow: 1;}#sk-container-id-1 div.sk-label:hover label.sk-toggleable__label {background-color: #d4ebff;}#sk-container-id-1 div.sk-serial::before {content: \"\";position: absolute;border-left: 1px solid gray;box-sizing: border-box;top: 0;bottom: 0;left: 50%;z-index: 0;}#sk-container-id-1 div.sk-serial {display: flex;flex-direction: column;align-items: center;background-color: white;padding-right: 0.2em;padding-left: 0.2em;position: relative;}#sk-container-id-1 div.sk-item {position: relative;z-index: 1;}#sk-container-id-1 div.sk-parallel {display: flex;align-items: stretch;justify-content: center;background-color: white;position: relative;}#sk-container-id-1 div.sk-item::before, #sk-container-id-1 div.sk-parallel-item::before {content: \"\";position: absolute;border-left: 1px solid gray;box-sizing: border-box;top: 0;bottom: 0;left: 50%;z-index: -1;}#sk-container-id-1 div.sk-parallel-item {display: flex;flex-direction: column;z-index: 1;position: relative;background-color: white;}#sk-container-id-1 div.sk-parallel-item:first-child::after {align-self: flex-end;width: 50%;}#sk-container-id-1 div.sk-parallel-item:last-child::after {align-self: flex-start;width: 50%;}#sk-container-id-1 div.sk-parallel-item:only-child::after {width: 0;}#sk-container-id-1 div.sk-dashed-wrapped {border: 1px dashed gray;margin: 0 0.4em 0.5em 0.4em;box-sizing: border-box;padding-bottom: 0.4em;background-color: white;}#sk-container-id-1 div.sk-label label {font-family: monospace;font-weight: bold;display: inline-block;line-height: 1.2em;}#sk-container-id-1 div.sk-label-container {text-align: center;}#sk-container-id-1 div.sk-container {/* jupyter's `normalize.less` sets `[hidden] { display: none; }` but bootstrap.min.css set `[hidden] { display: none !important; }` so we also need the `!important` here to be able to override the default hidden behavior on the sphinx rendered scikit-learn.org. See: https://github.com/scikit-learn/scikit-learn/issues/21755 */display: inline-block !important;position: relative;}#sk-container-id-1 div.sk-text-repr-fallback {display: none;}</style><div id=\"sk-container-id-1\" class=\"sk-top-container\"><div class=\"sk-text-repr-fallback\"><pre>KNeighborsClassifier(n_neighbors=1)</pre><b>In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. <br />On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.</b></div><div class=\"sk-container\" hidden><div class=\"sk-item\"><div class=\"sk-estimator sk-toggleable\"><input class=\"sk-toggleable__control sk-hidden--visually\" id=\"sk-estimator-id-1\" type=\"checkbox\" checked><label for=\"sk-estimator-id-1\" class=\"sk-toggleable__label sk-toggleable__label-arrow\">KNeighborsClassifier</label><div class=\"sk-toggleable__content\"><pre>KNeighborsClassifier(n_neighbors=1)</pre></div></div></div></div></div>"
      ],
      "text/plain": [
       "KNeighborsClassifier(n_neighbors=1)"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "knn.fit(X, y)  # 训练模型"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 4. 用模型推理(预测)用户的喜好"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "new_user = np.array([[3, 4]])\n",
    "prediction = knn.predict(new_user)  # 用模型推理(预测)用户的喜好"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 5. 数据可视化"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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nIhcw9WX3V85ETP3CNGkSdbvRUTy4fKrzwqSnJxseZgqQIcOHYiPj2fixIk888wz1K9fn2XLluUprkqaybc+Jt9JeAWageWYysRi8vLsw6IiLleY+xCpMBIRO5Sqoujqp03bevp037596Zt7wzYRuX5lZRXuPkS5y7OyCu4nIte9UlUUiYgU2jUe7mpFR4hEpBBcfkdrERERkdJARZGIiIgIKopEREREABVFIiIiIoCKIhERERFARZGIiIgIoKJIREREBFBRJCIiIgKoKBIREREBVBSJiIiIACqKRERERAAVRSIiIiKAiiIRERERQEWRiIiICKCiSERERARQUSQiIiICqCgSERERAVQUiYiIiAAqikREREQAFUUiIiIigIoiEREREUBFkYiIiAigokhEREQEUFEkIiIiAqgoEhEREQFUFImIiIgAKopEREREABVFIiIiIgD42LvC6NGjbbabTCYCAgKoV68effr0oWLFisUOTkRERKSk2F0Ubd++nW3btpGVlUXDhg0B+P333/H29iYiIoL//Oc/PPXUU6xfv56bbrrJ4QGLiIiIOIPdp8/69OnDHXfcwbFjx9i6dStbt27lyJEjREdHExsby9GjR7n11lt58sknrznWnDlzaNasGSEhIYSEhBAVFcWKFSvy7R8XF4fJZLJ6BQQE2JuCiIiISB52HymaOXMmCQkJhISEWNrKlSvHlClT6Nq1KyNHjmTSpEl07dr1mmPVqFGDl156ifr162MYBu+//z59+vRh+/btNG7c2OY6ISEh7Nmzx/LeZDLZm4KIiIhIHnYXRampqZw8eTLPqbE///yTtLQ0AMqXL8+lS5euOdadd95p9f6FF15gzpw5/Pjjj/kWRSaTibCwMHvDFhERESmQ3UVRnz59GDJkCK+99hpt2rQBYPPmzYwZM4aYmBgAfv75Zxo0aGDXuFlZWSxZsoTz588TFRWVb7/09HRq1apFdnY2kZGRvPjii/kWUACZmZlkZmZa3ucWbmazGbPZbFeM15I7nqPHLS08PT/w/ByVn/vz9ByVn/tzVo4l8ZmZDMMw7FkhPT2dJ598kg8++IDLly8D4OPjw6BBg5g1axZly5YlKSkJgBYtWlxzvB07dhAVFcXFixcJCgoiPj6enj172uy7adMm9u7dS7NmzUhNTeXVV19l7dq17Nq1ixo1athcZ8qUKUyd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0aW0tDTCw8Pp2rWrwz9Us9lMQkIC0dHR+Pr6OnTs0sDT8wPPz1H5uT9Pz1H5uT9n5VgSz1ctdFFkNpvx9/e3vPfz87NK1sfHp0jPPfPz86NevXoAtGrVis2bNzN79mzmzp2bp29YWFieI0InTpwgLCws3/H9/f2t4s7l6+vrtC+kM8cuDTw9P/D8HJWf+/P0HJWf+3N0jiXxedn1mI/ffvuN48ePAzkPgP3f//5nufLs1KlTDgkoOzvbag7QlaKioli9ejWjRo2ytCUkJOQ7B0lERESksOwqirp06cKVU5D+8Y9/AGAymTAMA5PJZNfGJ0yYQI8ePahZsybnzp0jPj6exMREVq5cCcDAgQOpXr06M2bMAGDkyJF06tSJ1157jV69erF48WK2bNnCu+++a9d2RURERK5W6KLowIEDDt/4yZMnGThwICkpKZQrV45mzZqxcuVKoqOjgZx5TF5ef981oEOHDsTHxzNx4kSeeeYZ6tevz7Jly6zmNomIiIgURaGLolq1ajl84/Pnzy9weWJiYp62vn370rdvX4fHIiIiItc3PftMREREBBVFIiIiIoCKIhERERFARZGIiIgIUMSi6PLly6xatYq5c+dy7tw5AI4dO2a5Z5GIiIiIu7HrPkUAhw4donv37iQnJ5OZmUl0dDTBwcG8/PLLZGZm8s477zgjThERERGnsvtI0ciRI2ndujVnzpwhMDDQ0n7XXXexevVqhwYnIiIiUlLsPlK0bt06Nm7ciJ+fn1V77dq1OXr0qMMCExERESlJdh8pys7Otvng1yNHjhAcHOyQoERERERKmt1FUdeuXXnjjTcs700mE+np6UyePJmePXs6MjYRERGREmP36bPXXnuNbt26cdNNN3Hx4kX69+/P3r17qVy5Mh999JEzYhQRERFxOruLoho1avDLL7+wePFifv31V9LT0xk6dCgDBgywmngtIiIi4k7sLooAfHx8uP/++x0di4iIiIjLFKoo+vLLL+nRowe+vr58+eWXBfbt3bu3QwITERERKUmFKopiYmI4fvw4oaGhxMTE5NvPZDLZvDJNREREpLQrVFGUnZ1t888iIiIinsLuS/IPHz7sjDhEREREXMruoqh27dp06tSJ9957jzNnzjgjJhEREZESZ3dRtGXLFtq2bcu0adOoWrUqMTExfPrpp2RmZjojPhEREZESYXdR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",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.title(\"User Movie Preference\", size=15) \n",
    "plt.xlabel(\"Movie A rating\")\n",
    "plt.ylabel(\"Movie B rating\")\n",
    "plt.grid()\n",
    "\n",
    "# 绘制原始样本点，要求不同的影片喜好类别用不同的颜色标记\n",
    "# 提示: 用scatter散点图绘制，用它的参数c实现不同的类别用不同的颜色标记\n",
    "plt.scatter(X[:, 0], X[:, 1], c=y, cmap='viridis')  # 绘制原始样本点，不同的影片喜好类别用不同的颜色标记\n",
    "\n",
    "# 绘制新数据点，用红色x标记，大小为8\n",
    "# 提示：用plt.plot()绘制，用它的参数marker实现不同的标记符号\n",
    "plt.plot(new_user[0, 0], new_user[0, 1], 'rx', markersize=8)  # 绘制新数据点，用红色x标记，大小为8\n",
    "\n",
    "# 新数据最近邻索引为第一个最近邻的索引\n",
    "dist, idx = knn.kneighbors(new_user)  # 新数据最近邻索引为第一个最近邻的索引\n",
    "nearest = X[idx[0][0]]  # 获取最近邻点的坐标，这是一个列表，第一个元素是x坐标，第二个元素是y坐标\n",
    "\n",
    "# 用红线标记新数据点与最近邻点的连接线\n",
    "# 提示：用plt.plot()绘制，用 r-- 实现红色虚线\n",
    "plt.plot([new_user[0, 0], nearest[0]], [new_user[0, 1], nearest[1]], 'r--')  # 用红线标记新数据点与最近邻点的连接线\n",
    "\n",
    "# 为每个点添加坐标文本  \n",
    "for x, y in zip(X[:, 0], X[:, 1]):\n",
    "    plt.text(x, y+0.1, f'({x}, {y})') \n",
    "\n",
    "# 为新数据点添加坐标文本\n",
    "plt.text(new_user[0,0], new_user[0,1]+0.1, f'({new_user[0,0]}, {new_user[0,1]})')\n",
    "plt.show()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.4"
  },
  "orig_nbformat": 4
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
